package com.ywk.miaohsa.rabbitmq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * Spring中@Bean注解用于告诉方法，产生一个Bean对象，然后这个Bean对象交给Spring管理。产生这个Bean对象的
 * 方法Spring只会调用一次，随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
 *
 * SpringIOC 容器管理一个或者多个bean，这些bean都需要在@Configuration注解下进行创建，在一个方法上
 * 使用@Bean注解就表明这个方法需要交给Spring进行管理。
 *
 *
 * rabbitmq使用方法：先声明队列和交换机，通过相应的方法进行两者绑定，MQSender发送消息时通过
 * 交换机发送给对应的队列，MQReceiver通过注解@RabbitListener去监听对应的队列是否有消息，有则执行
 * 相应方法处理消息
 */
@Configuration
public class MQConfig {
    private static Logger log = LoggerFactory.getLogger(MQConfig.class);

    public static final String MIAOSHA_QUEUE = "miaosha.queue";
    public static final String QUEUE = "queue";

    public static final String TOPIC_QUEUE1 = "topic.queue1";
    public static final String TOPIC_QUEUE2 = "topic.queue2";
    public static final String TOPIC_EXCHANGE = "topicExchange";

    public static final String FANOUT_EXCHANGE = "fanoutExchange";

    public static final String HEADER_QUEUE = "header.queue";
    public static final String HEADERS_EXCHANGE = "headersExchange";

    /**
     * Direct模式
     * 发送者直接将信息发送给接收者队列
     * */
    @Bean
    public Queue queue() {
        log.info("执行方法MQConfig.queue(),初始化RabbitMQ队列：queue");
        return new Queue(QUEUE, true);
    }

    /**
     * Topic模式 交换机Exchange
     * 发送者将信息交由方法TopicExchange对象，队列通过RountingKey绑定交换机TopicExchange对象，
     * 该对象按RountingKey分发给两个接收者队列TOPIC_QUEUE1和TOPIC_QUEUE2(能发送一条消息给多个队列)
     * */
    @Bean
    public Queue topicQueue1(){
        return new Queue(TOPIC_QUEUE1,true);
    }
    @Bean
    public Queue topicQueue2(){
        return new Queue(TOPIC_QUEUE2,true);
    }
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(TOPIC_EXCHANGE);
    }
    @Bean
    public Binding topicBinding1(){
        return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("topic.key1");
    }
    @Bean
    public Binding topicBinding2(){
        //*符号代表匹配一个字母，#符号代表匹配0到多个字母
        return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.#");
    }
    /**
         * Fanout模式 交换机Exchange（广播模式）
     * 队列通过绑定FanoutExchange（FanoutBinding1()做绑定的）就能接受到发送者发送的消息
     * */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange(FANOUT_EXCHANGE);
    }
    @Bean
    public Binding FanoutBinding1() {
        return BindingBuilder.bind(topicQueue1()).to(fanoutExchange());
    }
    @Bean
    public Binding FanoutBinding2() {
        return BindingBuilder.bind(topicQueue2()).to(fanoutExchange());
    }

    /**
     * Header模式 交换机Exchange
     *
     * */
    @Bean
    public HeadersExchange headersExchange(){
        return new HeadersExchange(HEADERS_EXCHANGE);
    }
    @Bean
    public Queue headerQueue1() {
        return new Queue(HEADER_QUEUE, true);
    }
    @Bean
    public Binding headerBinding() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("header1", "value1");
        map.put("header2", "value2");
        return BindingBuilder.bind(headerQueue1()).to(headersExchange()).whereAll(map).match();
    }

    @Bean
    public Queue miaoshaQueue(){
        log.info("执行方法MQConfig.miaoshaQueue()，初始化RabbitMQ队列：miaosha.queue");
        return new Queue(MIAOSHA_QUEUE,true);
    }
}
